#include "../include/index.h"
#include "../include/my_web.hpp"
#include "../include/my_wifi.hpp"
#include "../include/motor.hpp"
#include "../include/debug_info.hpp"
#include "../include/my_fs.hpp"
#include "../include/bambu.hpp"

#define HOSTNAME  "C3AMS"
#define WEB_DEBUG 1
#define WEB_BAMBU(x) do{\
                         if(WEB_DEBUG){\
                           Serial.print(String("WEB_BAMBU:") + x);\
                           dbg.ops->send(String("WEB_BAMBU:") + x);\
                           }\
                       }while(0)

String dir[3]={"停止","进料","退料"};

WebServer server(80);

static MY_WEB_LOG logQueue = {
  .unsendCount = 0,
  .isFull = false,
  .head = 0,
  .tail = 0,
};

void addLog(const String newLog) {
    logQueue.log[logQueue.tail] = newLog;
    logQueue.tail = (logQueue.tail + 1) % 21;

    // 检查队列是否满，如果满了，更新头部位置覆盖最旧日志
    if (logQueue.isFull) {
        logQueue.head = (logQueue.head + 1) % 21;
        logQueue.unsendCount++;
    }

    // 如果队列头尾相遇，意味着队列已满
    if (logQueue.tail == logQueue.head) {
        logQueue.isFull = true;
    }
}

String getNextLog(MY_WEB_LOG &logQueue) {
    // 检查队列是否为空
    if (logQueue.head == logQueue.tail && !logQueue.isFull) {
        return "";  // 队列为空
    }

    String logEntry = logQueue.log[logQueue.head];
    logQueue.head = (logQueue.head + 1) % 21;
    logQueue.isFull = false;  // 每次读取时，队列不再是满的

    return logEntry;
}

static void web_loop(){
  server.handleClient();
}

static void handleRoot(){
  server.send(200, "text/html", index_html);
}

static void handleCss(){
  server.send(200, "text/css", style_css);
}
static void handleJs(){
  server.send(200, "application/javascript", work_js);
}
static void handleNotFound() {
  String message = "File Not Found\n\n";

  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

static void handleMotorCtrl(){
  String payloadch = server.arg("ch");
  String payload = server.arg("value");
  if(payloadch == NULL)
  {
    Serial.println("bad motor_ctrl request");
    return;
  }else if(payloadch.toInt() > 4 || payloadch.toInt() < 0)
  {
    Serial.println("bad motor_ch request");
    return;
  }

  uint8_t chx = payloadch.toInt()-1;
  if (payload == "load") {
    motor.ops->load(motor.mt[chx]);
    addLog(payloadch+":LOAD");
  } else if (payload == "unload") {
    motor.ops->unload(motor.mt[chx]);
    addLog(payloadch+":UNLOAD");
  } else if (payload == "stop") {
    motor.ops->stop(motor.mt[chx]);
    addLog(payloadch+":STOP");
  }else {
    addLog(payloadch+":BAD MOTOR COMMAND");
  }
  Serial.println("motor:"+payloadch+payload);
  server.send(200, "text/plain", dir[motor.mt[chx]->direction]);
}

static void handleState()
{
  JsonDocument doc;
  // 添加 motor 数据
  doc["motor1"] = dir[motor.mt[0]->direction];
  doc["motor2"] = dir[motor.mt[1]->direction];
  doc["motor3"] = dir[motor.mt[2]->direction];
  doc["motor4"] = dir[motor.mt[3]->direction];
  doc["state"] = bambu.data->amsStatus;
  doc["ch"] = bambu.data->lastFilament.toInt() + 1;

  if (logQueue.head == logQueue.tail && !logQueue.isFull) {
      // 队列为空
  }else{
    JsonArray logArray = doc["log"].to<JsonArray>(); // 创建 log 数组

    // 如果有略过的日志，添加提示
    if (logQueue.unsendCount > 0) {
        logArray.add("丢失了 " + String(logQueue.unsendCount) + " 条日志");  // 添加略过日志的提示
        logQueue.unsendCount = 0;  // 重置略过计数
    }

    // 遍历队列中的日志，直到所有日志被读取
    while (logQueue.head != logQueue.tail || logQueue.isFull) {
        String logEntry = getNextLog(logQueue);  // 从队列获取下一条日志
        if (logEntry != "") {
            logArray.add(logEntry);  // 添加日志到 JSON 数组
        }
    }
  }
  
  String json;
  serializeJson(doc, json);
  server.send(200, "application/json", json);
}
static void handleAms()
{
  String payload_amsch = server.arg("ch");
  String payload_amsctrl = server.arg("value");

  //切换通道
  if(payload_amsch != NULL)
  {
    int32_t amsch = payload_amsch.toInt()-1; //1~4
    if(amsch <= 4 && amsch >= 0)
    {
      JsonDocument data;
      data["lastFilament"] =  amsch;
      bambu.data->lastFilament = amsch;
      my_fs.ops->write(data,"/data.json");
    }
    server.send(200, "text/plain", "OK");
  }else if(payload_amsctrl != NULL){
    bambu.ops->debugCtrl(payload_amsch);
    server.send(200, "text/plain", "OK");
  }else server.send(400, "text/plain", "Get MSG Err");

}
static void handleOptions()
{
  if (server.hasArg("plain")) {  // 检查是否有POST的内容
    String message = server.arg("plain");  // 获取POST请求中的数据
    WEB_BAMBU("POST内容: " + message + "\n");
    server.send(200, "text/plain", "OK");

    JsonDocument data;
    deserializeJson(data, message.c_str(), message.length());
    if((data)["wifiKey"].as<String>() == "null" || (data)["wifiName"].as<String>() == "null"){
      JsonDocument tdata;
      tdata  = my_fs.ops->read("/config.json");
      data["wifiKey"] = tdata["wifiKey"];
      data["wifiName"] = tdata["wifiName"];
    }
    my_fs.ops->write(data,"/config.json");
  } else {
    server.send(400, "text/plain", "POST MSG Err");
  }
}

static void init_http(void){
  index_html.replace("server_ip", my_wifi.cfg->ip);
  MDNS.begin(HOSTNAME);

  server.on("/", handleRoot);
  server.on("/styles.css",handleCss);
  server.on("/work2.js", handleJs);   //修改名字防止 浏览器缓存

  server.on("/motor", handleMotorCtrl);
  server.on("/state", handleState);
  server.on("/ams", handleAms);
  server.on("/options",HTTP_POST, handleOptions);
  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}


static MY_WEB_OPS ops ={
  .init = init_http,
  .loop = web_loop,
  .addLog = addLog,
};

MY_WEB my_web = {
  .ops = &ops,
  .log = &logQueue,
};

